﻿using System;
using System.Collections.Generic;

namespace NeuralNetworks.Simple.Console
{
	using NeuralNetworks.Neurons;

	class Program
	{
		
		static void Main(string[] args)
		{
			var mathResult = ComputeCoefs();

			var simpleNeuron = new SimpleNeuron();
			var learningList = GetLearningList();
			//var rnd = new Random();
			//while (learningList.Count != 0)
			//{
			//    var index = rnd.Next(learningList.Count);
			//    var learningValue = learningList[index];
			//    simpleNeuron.Learn(learningValue.Input, learningValue.Result);
			//    learningValue.Count--;
			//    if (learningValue.Count == 0)
			//        learningList.RemoveAt(index);
			//}
			for (int i = 0; i < learningList[0].Count; i++)
			{
				foreach (var learningValue in learningList)
				{
					simpleNeuron.Learn(learningValue.Input, learningValue.Result);
				}
			}

			System.Console.WriteLine("Mathematical results:");
			System.Console.WriteLine("M = {0}; C = {1}", mathResult[0], mathResult[1]);
			System.Console.WriteLine("");

			System.Console.WriteLine("NeuralNetwork results:");
			System.Console.WriteLine("M = {0}; C = {1}", simpleNeuron.M, simpleNeuron.C);
			System.Console.ReadKey();
		}

		static List<LearningValue> GetLearningList()
		{
			return new List<LearningValue>(8)
			          	{
			          		new LearningValue(0.3, 1.6),
			          		new LearningValue(0.35, 1.4),
			          		new LearningValue(0.4, 1.4),
			          		new LearningValue(0.5, 1.6),
			          		new LearningValue(0.6, 1.7),
			          		new LearningValue(0.8, 2.0),
			          		new LearningValue(0.95, 1.7),
			          		new LearningValue(1.1, 2.1)
			          	};
		}

		static double[] ComputeCoefs()
		{
			var ll = GetLearningList();
			double sumX = 0;
			double sumX2 = 0;
			double sumY = 0;
			double sumXY = 0;

			foreach (var t in ll)
			{
				sumX += t.Input;
				sumX2 += (System.Math.Pow(t.Input, 2));
				sumY += t.Result;
				sumXY += t.Input*t.Result;
			}

			var m = (ll.Count*sumXY - sumX*sumY)/(ll.Count*sumX2 - sumX*sumX);
			var c = (sumY - m*sumX)/ll.Count;
			return new[] {m, c};
		}
	}

	internal class LearningValue
	{
		public double Input;
		public double Result;
		public int Count;

		public LearningValue(double input, double result, int count)
		{
			Input = input;
			Result = result;
			Count = count;
		}

		public LearningValue(double input, double result) : this(input, result, 40000) { }
	}
}

